-- UIAwakeMain
-- Create by chendh
-- 觉醒主界面

local SCULPTOR_PET_ID = 125
local MAX_SHOW_SATUES_NUM = 11

-- UIAwakeMain继承自Layer
UIAwakeMain = class("UIAwakeMain", function()
    return cc.Layer:create();
end);

function UIAwakeMain.create()
    return UIAwakeMain.new();
end

-- 内部函数声明

-- 构造函数
function UIAwakeMain:ctor()
    -- 初始化
    self:setName("UIAwakeMain");
    local node = cc.CSLoader:createNode("layout/awake/AwakeMain.csb");
    self:addChild(node);
    self.node = node;

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 重绘
    self:redraw();

    -- 适配
    self:resize();
end

-- 适配
function UIAwakeMain:resize()
    local node = self.node;

    AlignM.fitToScreen(node, "bg");
    AlignM.alignToCenter(node, "background");
    AlignM.alignToCenter(node, "CT");
    AlignM.alignToBottomCenter(node, "BT");
end

-- 重绘界面
function UIAwakeMain:redraw()
    local node = self.node;
    local dungeonNode = findChildByName(node, "CT/dungeon");
    local carvingNode = findChildByName(node, "CT/carving");
    local jewelNode = findChildByName(node, "CT/jewel");
    local btnExtend = findChildByName(node, "BT/btn_extend");

    -- 如果还没结束指引，那么不显示扩建和珠宝熔炼
    if not AwakeM.isFinishGuide() then
        jewelNode:setVisible(false);
        btnExtend:setVisible(false);
    else
        jewelNode:setVisible(true);
        btnExtend:setVisible(true);
    end

    local dungeonBubble = findChildByName(node, "CT/dungeon/bubble");
    local carvingBubble = findChildByName(node, "CT/carving/bubble");
    local dungeonIcon = findChildByName(node, "CT/dungeon/bubble/icon");
    local carvingIcon = findChildByName(node, "CT/carving/bubble/icon");
    local statusLabel = findChildByName(node, "CT/carving/bubble/status");
    dungeonBubble:stopAllActions();
    carvingBubble:stopAllActions();
    statusLabel:setVisible(false);

    if not AwakeM.isFinishGuide() then
        -- 还没结束指引的时候，气泡需要特殊处理
        local awakeGuide = AwakeM.getGuideProgress();
        if awakeGuide < 1 then
            dungeonBubble:setVisible(false);
        elseif awakeGuide == 1 then
            dungeonBubble:setVisible(true);
            dungeonIcon:loadTexture(getHeroIconPath(PetM.getDefaultIcon(128)));
            dungeonIcon:setScale(0.8);
        elseif awakeGuide == 2 then
            dungeonBubble:setVisible(true);
            if AwakeM.calcFinishedAwakeDungeonNum() > 0 then
                dungeonIcon:loadTexture(getHeroIconPath(PetM.getDefaultIcon(128)));
                dungeonIcon:setScale(0.8);
            else
                dungeonIcon:loadTexture(getAwakeIconPath("awake_dungeon"));
                dungeonIcon:setScale(1);
                playBubbleAnima(dungeonBubble, false, nil, nil, nil, nil, 0.8);
            end
        else
            -- 如果任意冈布奥可以进入地牢试炼，那么显示地牢试炼的气泡
            if AwakeM.anyoneSlimeCanAwakeDungeon() then
                dungeonBubble:setVisible(true);
                dungeonIcon:loadTexture(getAwakeIconPath("awake_dungeon"));
                dungeonIcon:setScale(1);
                playBubbleAnima(dungeonBubble, false, nil, nil, nil, nil, 0.8);
            else
                dungeonBubble:setVisible(false);
            end
        end

        if awakeGuide < 1 then
            carvingBubble:setVisible(false);
        elseif awakeGuide >= 1 then
            carvingBubble:setVisible(true);
            carvingIcon:loadTexture(getHeroIconPath(PetM.getDefaultIcon(125)));
            carvingIcon:setScale(0.8);
        end
        return;
    end

    -- 如果任意冈布奥可以进入地牢试炼，那么显示地牢试炼的气泡
    if AwakeM.anyoneSlimeCanAwakeDungeon() then
        dungeonBubble:setVisible(true);
        dungeonIcon:loadTexture(getAwakeIconPath("awake_dungeon"));
        playBubbleAnima(dungeonBubble, false, nil, nil, nil, nil, 0.8);
        dungeonIcon:setScale(1);
    else
        dungeonBubble:setVisible(false);
    end

    -- 雕像区域气泡
    if AwakeM.getCarvingState() == AwakeM.CARVING_STATE_UPGRADING or
        AwakeM.getCarvingState() == AwakeM.CARVING_STATE_FINISH then
        -- 当前有雕像正在雕刻，显示雕像
        carvingBubble:setVisible(true);

        local heroId = AwakeM.getCarvingHeroId();
        local pet = PetM.getMyPet(heroId);
        carvingIcon:loadTexture(getHeroIconPath(pet:getIcon()));
        --carvingIcon:loadTexture(getAwakeIconPath("carving"));
        carvingIcon:setScale(0.9);

        -- 设置描边为2像素，黑色
        TextStyleM.setOutlineStyle(statusLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);
        TextStyleM.setTextStyle(statusLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BRIGHT_YELLOW, true, -2, 1.2);

        local msg;
        if AwakeM.getCarvingState() == AwakeM.CARVING_STATE_FINISH then
            if self.tickNode then
                self.tickNode:stopAllActions();
            end

            msg = getLocStr("awake_carving_finish");
            statusLabel:setVisible(true);
            statusLabel:setString(msg);

            -- 文字跳动
            setJumpStop("awakeMain", true);

            local nameCount = string.getWCharCount(statusLabel:getString());
            setTextJump(nameCount, statusLabel, self.node, "awakeMain");
        else
            -- 显示倒计时
            statusLabel:setVisible(true);

            self:startTick(statusLabel);
        end

        -- 呼吸效果
        playBubbleAnima(carvingBubble, false, nil, 0.95, 0.98, 1, 0.7);
    elseif AwakeM.anyoneSlimeCanCarving() or not AwakeM.isFinishGuide() then
        -- 如果任意冈布奥可以雕刻雕像，那么显示雕像的气泡
        carvingBubble:setVisible(true);
        carvingIcon:loadTexture(getAwakeIconPath("carving"));
        carvingIcon:setScale(0.88);

        -- 呼吸效果
        playBubbleAnima(carvingBubble, false, nil, nil, nil, nil, 0.8);
    else
        carvingBubble:setVisible(false);
    end

    -- 绘制珠宝熔炼区域的工匠冈布奥
    if not jewelNode.initSlime then
        jewelNode.initSlime = true;
        self:initSlimeNode(jewelNode, 126);
    end

    -- 播放界面光效
    if not self.snowEffect then
        self.snowEffect = true;

        local bottomNode = findChildByName(self.node, "background/bottom");
        local middleNode = findChildByName(self.node, "background/middle");
        local topNode = findChildByName(self.node, "background/top");
        playEffect(bottomNode, 1352);
        local _, effect = playEffect(middleNode, 1353);
        local _, effect1 = playEffect(topNode, 1354);
        playEffect(middleNode, 1355);
        playEffect(bottomNode, 1356);

        -- 门洞发光的光效需要高亮
        local children = effect:getChildren();
        local len = table.getn(children)
        for i = 1, len do
            local child = children[i];

            local children2 = child:getChildren();
            local len2 = table.getn(children2)
            for j = 1, len2 do
                local child2 = children2[j];
                -- 由于美术保存图片后亮光效果消失，故而转到程序实现
                setHighLightMode(child2, true, 0.2);
                child2:setBlendFunc(gl.SRC_COLOR, gl.ONE);
            end
        end

        -- 雪花前景光效要调整下透明度
        effect1:setOpacity(150);
    end
end

-- 冈布奥图标初始化
function UIAwakeMain:initSlimeNode(child, classId)
    if classId == nil then
        child:setVisible(false);
        return;
    end

    -- 显示冈布奥模型
    local headImg = ccui.ImageView:create();
    local iconPath = getHeroIconPath(PetM.getDefaultIcon(classId));
    headImg:setPosition(cc.p(child:getContentSize().width / 2, 0));
    headImg:setAnchorPoint(cc.p(0.5, 0));
    headImg:setScale(0.9);
    headImg:loadTexture(iconPath);
    child:addChild(headImg);

    local oldScaleX = headImg:getScaleX();
    local oldScaleY = headImg:getScaleY();

    -- 图片需要播放呼吸效果
    local scaleUp   = cc.ScaleTo:create(1, 1 * oldScaleX, 1 * oldScaleY);
    local scaleDown = cc.ScaleTo:create(1, 1 * oldScaleX, 0.95 * oldScaleY);

    headImg:runAction(cc.RepeatForever:create(cc.Sequence:create(scaleUp, scaleDown)));
end

-- 显示倒计时
function UIAwakeMain:startTick(statusLabel)
    if self.tickNode == nil then
        self.tickNode = cc.Node:create();
        self:addChild(self.tickNode);
    end

    self.tickNode:stopAllActions();

    local function tick()
        -- 当前剩余时间
        local finishTime = AwakeM.getCarvingFinishTime();
        local serverTime = TimeM.getServerTime();
        local leftTime = finishTime - serverTime;
        if leftTime < 0 then
            leftTime = 0;
        end

        local delay = 0.5;
        if leftTime < 3600 then
            local hours = math.floor(leftTime / 3600);
            local mins =  math.floor((leftTime % 3600) / 60);
            local secs =  (leftTime % 3600) % 60;

            local desc = string.format("%02d:%02d:%02d", hours, mins, secs);
            statusLabel:setString(desc);
            delay = 0.5;
        else
            local hours = math.floor(leftTime / 3600);
            statusLabel:setString(hours.."h");
            if hours > 1 then
                delay = 60;
            else
                delay = 1;
            end
        end

        if leftTime > 0 then
            performWithDelay(self.tickNode, tick, delay);
        else
            self:redraw();
        end
    end

    tick();
end

-- 注册事件处理回调函数
function UIAwakeMain:registerEventCallback()
    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            EventMgr.removeAll("UIAwakeMain");

            -- 显示主地图
            if UIMgr.getCurrentScene().mainMap then
                UIMgr.getCurrentScene().mainMap:show();
                local bgm = AudioM.queryFormAudioInfo("UIMainMap", "open_bgm");
                if bgm ~= nil and bgm ~= "" then
                    AudioM.playBgMusic(bgm);
                end
            end

            UIMgr.tryClearUnusedTextures();
        elseif eventType == "enter" then
            -- 这里把主地图隐藏清楚，降低GL calls
            if UIMgr.getCurrentScene().mainMap then
                UIMgr.getCurrentScene().mainMap:hide();
            end
        end
    end);

    -- 注册获得焦点的回调
    EventMgr.register("UIAwakeMain", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UIAwakeMain" then
            self:redraw();

            UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_MONEY, TOPMENU_FRAME_RUINS_SCRAP);

            -- 尝试触发指引
            self:tryToGuide();

            -- 检查工匠
            self:checkSlimeEffect();

            local btNode = findChildByName(self.node, "BT");
            btNode:setVisible(true);

            -- 雕像建造完成时，尝试触发缓存的冈布奥事件
            if para["lose"] == "UIHeroUpgradeRankEffect" then
                SlimeEventM.triggerCacheEvents();
            end
        elseif para["lose"] == "UIAwakeMain" then
            local btNode = findChildByName(self.node, "BT");
            btNode:setVisible(false);
        end
    end);
end

-- 注册点击事件
function UIAwakeMain:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("ship_return");
            UIMgr.getCurrentScene():removeFormByName("UIAwakeMain");

            -- 加载主界面资源
            if DungeonM.dungeonType == DUNGEON_TYPE_AWAKE then
                UIMgr.getCurrentScene().mainMap:show();
                UIMgr.getCurrentScene().mainMap:reloadImages();
                DungeonM.dungeonType = DUNGEON_TYPE_NORMAL;
            end
        end
    end
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));
    AddBackEventHandler(self, btnBack, onBackClick);

    -- 注册 扩建 按钮点击事件
    local btnExtend = findChildByName(self.node, "BT/btn_extend");
    local function onExtendClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 如果还没结束指引，那么不响应
            if not AwakeM.isFinishGuide() then
                return;
            end

            -- 打开扩建界面
            -- TODO
            require "game/ui/form/sky_city/UIRelicStrengthen";
            local uiForm = UIRelicStrengthen.create("awake");
            UIMgr.getCurrentScene():addForm(uiForm);
        end
    end
    TextStyleM.setTextStyle(btnExtend, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnExtend:setTitleText(getLocStr("btn_text_build2"));
    btnExtend:addTouchEventListener(onExtendClick);

    -- 注册 试炼区域 按钮点击事件
    local dungeonPanel = findChildByName(self.node, "CT/dungeon");
    local function onDungeonClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 如果还没指引，那么弹出下指引对话
            local curProgress = AwakeM.getGuideProgress();
            if curProgress < 2 then
                -- 对话结束回调
                local function callback()
                    AwakeM.setGuideProgress(2);
                end

                -- 弹出觉醒的指引对话3
                startDialogueTemplate("awake_talk3", callback);

                return;
            elseif curProgress == 2 then
                if AwakeM.calcFinishedAwakeDungeonNum() > 0 then
                    -- 对话结束回调
                    local function callback()
                        AwakeM.setGuideProgress(3);
                    end

                    -- 弹出觉醒的指引对话4
                    startDialogueTemplate("awake_talk4", callback);
                    return;
                end
            end

            -- 打开试炼界面
            require "game/ui/form/awake/UIAwakeDungeon";
            local uiAwakeDungeon = UIAwakeDungeon.create();
            UIMgr.getCurrentScene():addForm(uiAwakeDungeon);
        end
    end
    dungeonPanel:addTouchEventListener(onDungeonClick);

    -- 注册 雕像区域 按钮点击事件
    local carvingPanel = findChildByName(self.node, "CT/carving");
    local function onCarvingClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 如果还没指引，那么弹出下指引对话
            local curProgress = AwakeM.getGuideProgress();
            if curProgress <= 2 then
                -- 弹出觉醒的指引对话2
                startDialogueTemplate("awake_talk2");

                return;
            elseif curProgress == 3 then
                -- 对话结束回调
                local function callback()
                    AwakeM.setGuideProgress(4);
                end

                -- 弹出觉醒的指引对话5
                startDialogueTemplate("awake_talk5", callback);
                return;
            elseif curProgress == 4 then
                -- 招募按钮回调
                local function okFunc()
                    if AwakeM.calcFinishedAwakeDungeonNum() < AwakeM.recruitPetNumLimit() then
                        alert(getLocStr("trial_slime_not_enough"));
                    elseif ME.user.dbase:query("money") < AwakeM.recruitSculptorCostMoney() then
                        alert(getLocStr("money_not_enough"));
                    else
                        -- 招募
                        -- 对话结束回调
                        local function callback()
                            AwakeM.setGuideProgress(5);
                        end

                        -- 弹出觉醒的指引对话4
                        startDialogueTemplate("awake_talk6", callback);
                    end
                end

                local title = PetM.query(SCULPTOR_PET_ID, "name");
                local desc = getLocStr("sculptor_desc");
                local icon = getHeroIconPath(PetM.getDefaultIcon(SCULPTOR_PET_ID));
                local okText = getLocStr("btn_text_recruit");
                local okBtnEnable = true;
                local extraPara = {["costDesc"] = string.format(getLocStr("sculptor_require_desc"),
                                            AwakeM.recruitPetNumLimit(), AwakeM.recruitSculptorCostMoney()),
                    ["okBtnEnable"] = okBtnEnable, ["offset"] = {0, 0}};

                -- 弹出雕刻家招募界面
                require "game/ui/form/sky_city/UIAirShipFix";
                local uiAirShipFix = UIAirShipFix.create(title, desc, icon, okText, okFunc, extraPara);
                UIMgr.getCurrentScene():addForm(uiAirShipFix);

                return;
            end

            -- 打开雕像界面
            require "game/ui/form/awake/UIAwakeCarvingMain"
            local uiForm = UIAwakeCarvingMain.create();
            UIMgr.getCurrentScene():addForm(uiForm);
        end
    end
    carvingPanel:addTouchEventListener(onCarvingClick);

    -- 注册 珠宝区域 按钮点击事件
    local jewelPanel = findChildByName(self.node, "CT/jewel");
    local function onJewelClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 如果还没结束指引，那么不响应
            if not AwakeM.isFinishGuide() then
                return;
            end

            -- 打开珠宝熔炼界面
            -- TODO
            require "game/ui/form/awake/UIAwakePearlList";
            local uiForm = UIAwakePearlList.create();
            UIMgr.getCurrentScene():addForm(uiForm);
        end
    end
    jewelPanel:addTouchEventListener(onJewelClick);
end

-- 尝试触发指引
function UIAwakeMain:tryToGuide()
    local curProgress = AwakeM.getGuideProgress();
    if curProgress <= 0 then
        -- 对话结束回调
        local function callback()
            AwakeM.setGuideProgress(1);
        end

        -- 弹出觉醒的指引对话1
        startDialogueTemplate("awake_talk1", callback);
    end
end

-- 检查工匠光效
function UIAwakeMain:checkSlimeEffect()
    local effectParent = findChildByName(self.node, "background/middle/effect_parent");
    local workerId = SkyRelicFunctionM.getIdsByRule("sculptor");
    if SkyRelicFunctionM.getLevel(workerId) < 1 then
        -- 没有挖掘工
        self.hasEffect = false;
        effectParent:setVisible(false);
        return;
    else
        self:slimeEffect();
    end
end

local EFFECT_WORKERS = 6;
-- 史莱姆工匠光效
function UIAwakeMain:slimeEffect()
    if self.hasEffect then
        return;
    end

    self.hasEffect = true;

    -- 特殊动画冈布奥
    local effectList = {1831, 1832, 1832, 1831, 1832, 1842};
    local offsetList = {{0, -35}, {15, -30}, {35, -25}, {0, -15}, {0, -15}, {0, -30}};
    local scale = {{-0.5, 0.5}, {-0.5, 0.5}, {-0.5, 0.5}, {-0.6, 0.6}, {0.5, 0.5}, {0.5, 0.5}};
    local effectParent = findChildByName(self.node, "background/middle/effect_parent");
    effectParent:setVisible(true);

    local delayTime = {50, 1, 50, 1, 30, 10};
    for i = 1, EFFECT_WORKERS do
        local pos = effectParent:getChildByName("pos"..i);
        local offset = offsetList[i];
        pos:stopAllActions();
        pos:removeAllChildren();

        local function callback()
            playEffect(pos, effectList[i], offset[1], offset[2]);
        end
        -- 延迟一下，避免一样的光效同频率
        performWithDelay(self.node, callback, delayTime[i]/100);

        -- 翻转一下
        pos:setScaleX(scale[i][1]);
        pos:setScaleY(scale[i][2]);
    end
end